#include "stdafx.h"
//-------------------------------------------------------------------------------------------------
//Boundary.cpp  - Behaviour and Properties of a Boundary (or set of points defining a closed shape ) within an Image        
//-------------------------------------------------------------------------------------------------
//FreeBSD License
//Copyright 2011 Will Stott All rights reserved.
//
//Redistribution and use in source and binary forms, with or without modification, are
//permitted provided that the following conditions are met:
//
//   1. Redistributions of source code must retain the above copyright notice, this list of
//      conditions and the following disclaimer.
//
//   2. Redistributions in binary form must reproduce the above copyright notice, this list
//      of conditions and the following disclaimer in the documentation and/or other materials
//      provided with the distribution.
//
//THIS SOFTWARE IS PROVIDED BY Will Stott ``AS IS'' AND ANY EXPRESS OR IMPLIED
//WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
//FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Will Stott OR
//CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
//CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
//SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
//ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
//NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
//ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//The views and conclusions contained in the software and documentation are those of the
//authors and should not be interpreted as representing official policies, either expressed
//or implied, of Will Stott.
//
//----Authors--------------------------------------------------------------------------------------
//created by: will.stott@ucl.ac.uk Feb 2011
//
//----Comments-------------------------------------------------------------------------------------
//
//-------------------------------------------------------------------------------------------------

#include "Boundary.h"


Boundary::Boundary(void)
	:  _Complete(false),
	  _Extent(0,0,0,0)
{
	
}


Boundary::~Boundary(void)
{
	ClearAllPoints();
}


size_t Boundary::Start(int xVal, int yVal)			//adds first point to describe the shape, return zero-based index of point added (0)
{
	size_t rc = 0;

	EraseAllPoints();
	rc = Add(xVal, yVal);				

	return rc;										//should return 0 - index of first point added to boundary
}


size_t Boundary::Extend(int xVal, int yVal)			//adds another point to describe the shape, return zero-based index of point added
{
	size_t rc = 0;
	if ( _Points.size() > 0	)						//cannot extend a boundary that hasn't been started - i.e. call Start() before Extend()
	{
		rc = Add(xVal, yVal);
	}
	return rc;										//should return > 0 - index of point added to boundary
}


size_t Boundary::Close(int xVal, int yVal)			//creates last point at same position as first point, return zero-based index of last point, or 0 if fail
{
	size_t rc = 0;

	int cnt = 0;
	if ( (cnt = Extend(xVal, yVal)) > 0)
	{
		if (cnt > 0 )
		{
			std::vector<ImagePt*>::iterator c1_Iter = _Points.begin();
			ImagePt* startPt = *c1_Iter;
			if (startPt)
			{
				rc = Add(startPt->x, startPt->y);
				if (rc >  0)
				{
					_Complete = true;
				}
			}
		}
	}
	return rc;
}


void Boundary::EraseAllPoints()
{
	ClearAllPoints();
}

//............................................................................................
//private member functions
//............................................................................................

void	Boundary::SetExtent(int xVal, int yVal)
{
	if ( _Points.size() == 1 )
	{
		_Extent.SetTopLeft(xVal,  yVal);
		_Extent.SetBotRight(xVal, yVal);
	}
	else
	{
		if ( _Points.size() > 1 )
		{
			if (xVal < _Extent.GetTopLeft().x )
				_Extent.SetTopLeftX(xVal);
			if (yVal < _Extent.GetTopLeft().y)
				_Extent.SetTopLeftY(yVal);
			if (xVal > _Extent.GetBotRight().x ) 
				_Extent.SetBotRightX(xVal);
			if (yVal > _Extent.GetBotRight().y)
				_Extent.SetBotRightY(yVal);
		}
	}
}

size_t Boundary::Add(int xVal, int yVal)			//adds another point to describe the shape, return zero-based index of point added
{
	_Points.push_back(new ImagePt(xVal, yVal));
	SetExtent(xVal, yVal);
	return _Points.size()-1;						//return index of point added to boundary
}

bool Boundary::ClearAllPoints()
{
	bool rc = false;

	size_t cnt = _Points.size();
	if (cnt > 0 )
	{
		for (size_t x = 0; x < cnt; x++)
			delete  _Points[x];
		_Points.clear();
		rc = true;
	}
	_Complete = false;

	return rc;
}

//-------------------------------------------------------------------------------------------------
//			E N D   O F   F I L E
//-------------------------------------------------------------------------------------------------

